<template>
  <div ref="barChartRef" />
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, markRaw, defineProps } from "vue";
import * as echarts from "echarts";

// 接收参数
const props = defineProps({
  title: String,
  unit: String,
  data: {
    type: Array as string[],
    default: {}
  }
});
const name = props.data.map(item => item.name);
const value = props.data.map(item => item.value);
const dataLength = props.data.length;
const title = props.title;
const unit = props.unit;

// 图表绘制逻辑
const barChartRef = ref<HTMLDivElement | null>(null);
const barChartRefInstance = ref<echarts.ECharts | null>(null);
const initBarOption = ref<echarts.EChartOption>({});

const color: string[] = [
  "#2b89f8",
  "#fa512a",
  "#00ffff",
  "#409B5C",
  "#ffe000",
  "#ffa800",
  "#ff5b00"
];
let toolTimer = ref<any>(null);
const offsetX = 16;
const offsetY = 8;
// 绘制左侧面
const CubeLeft = echarts.graphic.extendShape({
  shape: {
    x: 0,
    y: 0
  },
  buildPath: function (ctx, shape) {
    const xAxisPoint = shape.xAxisPoint;
    const c0 = [shape.x, shape.y];
    const c1 = [shape.x - offsetX, shape.y - offsetY];
    const c2 = [xAxisPoint[0] - offsetX, xAxisPoint[1] - offsetY];
    const c3 = [xAxisPoint[0], xAxisPoint[1]];
    ctx
      .moveTo(c0[0], c0[1])
      .lineTo(c1[0], c1[1])
      .lineTo(c2[0], c2[1])
      .lineTo(c3[0], c3[1])
      .closePath();
  }
});
// 绘制右侧面
const CubeRight = echarts.graphic.extendShape({
  shape: {
    x: 0,
    y: 0
  },
  buildPath: function (ctx, shape) {
    const xAxisPoint = shape.xAxisPoint;
    const c1 = [shape.x, shape.y];
    const c2 = [xAxisPoint[0], xAxisPoint[1]];
    const c3 = [xAxisPoint[0] + offsetX, xAxisPoint[1] - offsetY];
    const c4 = [shape.x + offsetX, shape.y - offsetY];
    ctx
      .moveTo(c1[0], c1[1])
      .lineTo(c2[0], c2[1])
      .lineTo(c3[0], c3[1])
      .lineTo(c4[0], c4[1])
      .closePath();
  }
});
// 绘制顶面
const CubeTop = echarts.graphic.extendShape({
  shape: {
    x: 0,
    y: 0
  },
  buildPath: function (ctx, shape) {
    const c1 = [shape.x, shape.y];
    const c2 = [shape.x + offsetX, shape.y - offsetY]; //右点
    const c3 = [shape.x, shape.y - offsetX];
    const c4 = [shape.x - offsetX, shape.y - offsetY];
    ctx
      .moveTo(c1[0], c1[1])
      .lineTo(c2[0], c2[1])
      .lineTo(c3[0], c3[1])
      .lineTo(c4[0], c4[1])
      .closePath();
  }
});
// 注册三个面图形
echarts.graphic.registerShape("CubeLeft", CubeLeft);
echarts.graphic.registerShape("CubeRight", CubeRight);
echarts.graphic.registerShape("CubeTop", CubeTop);

initBarOption.value = {
  title: {
    show: false,
    text: "各科药品占比",
    left: "center",
    textStyle: {
      color: "#fff"
    }
  },
  tooltip: {
    trigger: "axis",
    axisPointer: {
      type: "shadow"
    },
    formatter: function (params) {
      const item = params[1];
      return `<p style="color: ${params[0].color}">${item.name}:${item.value}${unit}</p>`;
    }
  },
  grid: {
    top: "18%",
    left: "3%",
    right: "0%",
    bottom: "0%",
    containLabel: true
  },
  xAxis: {
    type: "category",
    data: name,
    axisLine: {
      show: true,
      lineStyle: {
        color: "#ffffff"
      }
    },
    axisTick: {
      show: false
    },
    axisLabel: {
      fontSize: 13,
      interval: 1
    }
  },
  yAxis: {
    name: title + "(" + unit + ")",
    type: "value",
    axisLine: {
      show: false,
      lineStyle: {
        // width: 1,
        color: "#ffffff"
      }
    },
    splitLine: {
      show: false,
      lineStyle: {
        // width: 1,
        type: "dashed",
        color: "#ffffff"
      }
    },
    axisTick: {
      show: false
    },
    axisLabel: {
      fontSize: 13
    }
    // boundaryGap: ['20%', '20%'],
  },
  series: [
    // 柱体
    {
      name: "",
      type: "custom",
      renderItem: (params, api) => {
        const location = api.coord([api.value(0), api.value(1)]);
        return {
          type: "group",
          children: [
            {
              type: "CubeLeft",
              shape: {
                api,
                xValue: api.value(0),
                yValue: api.value(1),
                x: location[0],
                y: location[1],
                xAxisPoint: api.coord([api.value(0), 0])
              },
              style: {
                fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  {
                    offset: 0,
                    color: "#40c3c8"
                  },
                  {
                    offset: 1,
                    color: "#6baaae"
                  }
                ])
              }
            },
            {
              type: "CubeRight",
              shape: {
                api,
                xValue: api.value(0),
                yValue: api.value(1),
                x: location[0],
                y: location[1],
                xAxisPoint: api.coord([api.value(0), 0])
              },
              style: {
                fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  {
                    offset: 0,
                    color: "#40c3c8"
                  },
                  {
                    offset: 1,
                    color: "#6baaae"
                  }
                ])
              }
            },
            {
              type: "CubeTop",
              shape: {
                api,
                xValue: api.value(0),
                yValue: api.value(1),
                x: location[0],
                y: location[1],
                xAxisPoint: api.coord([api.value(0), 0])
              },
              style: {
                fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  {
                    offset: 0,
                    color: "#40c3c8"
                  },
                  {
                    offset: 1,
                    color: "#6baaae"
                  }
                ])
              }
            }
          ]
        };
      },
      data: value
    },
    // bar顶部数量
    {
      name: "",
      type: "bar",
      label: {
        normal: {
          show: true,
          position: "inside",
          formatter: e => {
            return `${e.value}${unit}`;
          },
          fontSize: 13,
          color: "#ffffff",
          offset: [0, 0]
        }
      },
      itemStyle: {
        color: "transparent"
      },
      tooltip: {},
      data: value
    }
  ]
};

const initBarChart = () => {
  if (barChartRef.value) {
    barChartRefInstance.value = markRaw(echarts.init(barChartRef.value));
    barChartRefInstance.value.setOption(initBarOption.value, true);
  }
};

// tooltip自动轮播 若使用请做销毁处理
if (initBarOption.value && typeof initBarOption.value === "object") {
  let index = 0;
  toolTimer.value = setInterval(function () {
    barChartRefInstance.value.dispatchAction({
      type: "showTip",
      seriesIndex: 0,
      dataIndex: index
    });
    index++;
    if (index >= dataLength) {
      index = 0;
    }
  }, 3000);
}

// 挂载后动作 -- 初始化图表
onMounted(() => {
  initBarChart();
  // 图表自适应
  window.addEventListener("resize", () => {
    if (barChartRefInstance.value) {
      barChartRefInstance.value.resize();
    }
  });
});

// 销毁前动作 -- 销毁图表
onBeforeUnmount(() => {
  if (barChartRefInstance.value) {
    barChartRefInstance.value.dispose();
  }
  if (toolTimer.value) {
    clearInterval(toolTimer.value);
  }
});
</script>

<style scoped lang="scss"></style>
